Drought & vegetation condition • VCI & TCI

VHI – Vegetation Health Index

VHI is a combined drought and vegetation-condition index that merges the Vegetation Condition Index (VCI) with the Temperature Condition Index (TCI) to represent overall vegetation health under water and thermal stress.


VHI overview concept & use-cases

What does VHI measure?

VHI combines information about greenness anomalies (from NDVI) through VCI and thermal anomalies (from LST / brightness temperature) through TCI. High VHI indicates healthy, unstressed vegetation; low VHI indicates drought or heat-stressed vegetation.

  • Operational drought monitoring at regional to global scales.
  • Crop condition and yield-forecasting studies.
  • Early warning for agricultural drought and famine risk.
  • Long-term climate–vegetation interaction analysis.

Note: VHI is typically computed from time-series NDVI and LST (or brightness temperature) after deriving VCI and TCI over a reference period.

VHI, VCI and TCI formulas

VCI & TCI from NDVI and LST / BT
VCI = 100 · (NDVI − NDVImin) / (NDVImax − NDVImin)
TCI = 100 · (BTmax − BT) / (BTmax − BTmin)

NDVImin, NDVImax, BTmin, BTmax are typically computed per pixel over a multi-year reference period (e.g. 10+ years).

VHI (default weighting)
VHI = 0.5 · VCI + 0.5 · TCI

The weighting factors (0.5 / 0.5) are commonly used, but can be adjusted (e.g. VHI = a·VCI + (1−a)·TCI) based on regional calibration.

Required inputs

Time-series components

Component Source
NDVI Visible & NIR bands (e.g. AVHRR, MODIS, Landsat, Sentinel-2)
BT / LST Thermal bands or LST products (e.g. AVHRR, MODIS, Landsat)
NDVImin/max Per-pixel long-term NDVI min/max over reference period
BTmin/max Per-pixel long-term BT / LST min/max over reference period

Tip: VHI is most meaningful when computed over consistent, long-term, cloud-free time-series (e.g. dekadal AVHRR/MODIS composites).

Interpreting VHI (typical ranges)

VHI value Vegetation health / drought level
> 60–70 Healthy vegetation, no significant stress
40–60 Mild stress / watch conditions
20–40 Moderate to severe drought stress
< 20 Extreme vegetation stress / drought

Thresholds vary by region and ecosystem; always validate against local climate and crop conditions.

Using VHI in Google Earth Engine (conceptual example)

  1. Build NDVI and BT / LST time-series over a multi-year period.
  2. Compute per-pixel NDVImin/max and BTmin/max over the reference period.
  3. For a target date / composite, compute VCI and TCI.
  4. Combine them into VHI = 0.5 · VCI + 0.5 · TCI (or other weights).
// VHI – conceptual example (using MODIS NDVI & LST) in Google Earth Engine
var roi = /* your geometry here */;

// Example: MODIS NDVI & LST 16-day composites
var ndviCol = ee.ImageCollection('MODIS/061/MOD13Q1')
  .select('NDVI')
  .filterBounds(roi);

var lstCol = ee.ImageCollection('MODIS/061/MOD11A2')
  .select('LST_Day_1km')
  .filterBounds(roi);

// Reference period (e.g. 2003–2020)
var refNdvi = ndviCol.filterDate('2003-01-01', '2020-12-31');
var refLst  = lstCol.filterDate('2003-01-01', '2020-12-31');

// Long-term NDVI min/max
var ndviRefMin = refNdvi.min().rename('NDVI_min');
var ndviRefMax = refNdvi.max().rename('NDVI_max');

// Long-term LST min/max (convert to Kelvin using scale factor)
var lstRefScaled = refLst.map(function(img) {
  return img.multiply(0.02); // MODIS LST scale
});
var lstRefMin = lstRefScaled.min().rename('LST_min');
var lstRefMax = lstRefScaled.max().rename('LST_max');

// Target period (e.g. current season)
var ndviNow = ndviCol.filterDate('2023-06-01', '2023-08-31').mean()
  .multiply(0.0001)  // NDVI scale factor for MODIS
  .rename('NDVI');

var lstNow = lstCol.filterDate('2023-06-01', '2023-08-31').mean()
  .multiply(0.02)    // LST scale factor
  .rename('LST');

// Stack bands
var stack = ndviNow.addBands(ndviRefMin).addBands(ndviRefMax)
  .addBands(lstNow).addBands(lstRefMin).addBands(lstRefMax);

// Compute VCI and TCI
var vci = stack.expression(
  '100 * (ndvi - ndvi_min) / (ndvi_max - ndvi_min + 1e-6)',
  {
    ndvi:     stack.select('NDVI'),
    ndvi_min: stack.select('NDVI_min'),
    ndvi_max: stack.select('NDVI_max')
  }
).rename('VCI');

var tci = stack.expression(
  '100 * (lst_max - lst) / (lst_max - lst_min + 1e-6)',
  {
    lst:     stack.select('LST'),
    lst_min: stack.select('LST_min'),
    lst_max: stack.select('LST_max')
  }
).rename('TCI');

// VHI = 0.5 * VCI + 0.5 * TCI
var vhi = vci.multiply(0.5).add(tci.multiply(0.5)).rename('VHI');

// Visualisation
Map.centerObject(roi, 5);
Map.addLayer(vhi, {
  min: 0, max: 100,
  palette: ['#7f1d1d','#b91c1c','#f97316','#eab308','#22c55e','#16a34a']
}, 'VHI - Vegetation Health Index');

// Optional export
Export.image.toDrive({
  image: vhi,
  description: 'VHI_MODIS_example',
  region: roi,
  scale: 1000,
  maxPixels: 1e13
});

Important: this is a conceptual implementation. Adapt products (AVHRR, MODIS, Sentinel, etc.), reference period, and scaling factors according to your data source and study requirements.

Part of the Start4IT Remote Sensing Indices Library. More indices & ready-to-use code: www.start4it.com/rs-indices